﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Jenvin.Library.Functional
{
    class Program
    {
        static int Fib(int x, int y)
        {
            return y == 0 ? x : Fib(y, x % y);
        }
        static void Main(string[] args)
        {
            var fac = LambdaRecursion.Self<int, int>((f, x) => x <= 1 ? 1 : x * f(f, x - 1));
            var fib = LambdaRecursion.Self<int, int>((f, x) => x <= 1 ? 1 : f(f, x - 1) + f(f, x - 2));
            var gcd = LambdaRecursion.Self<int, int, int>((f, x, y) => y == 0 ? x : f(f, y, x % y));

            var facY = LambdaRecursion.Fix<int, int>(f => x => x <= 1 ? 1 : x * f(x - 1));
            var fibY = LambdaRecursion.Fix<int, int>(f => x => x <= 1 ? 1 : f(x - 1) + f(x - 2));
            var gcdY= LambdaRecursion.Fix<int, int, int>(f => (x, y) => y == 0 ? x : f(y, x % y));


            Fib(1, 2); // JIT“预热”
            var gcdMake = LambdaRecursion.Self<int, int, int>(
                (f, x, y) => y == 0 ? x : f(f, y, x % y));
            var gcdFix = LambdaRecursion.Fix<int, int, int>(
                f => (x, y) => y == 0 ? x : f(y, x % y));

           // CodeTimer.Initialize();

            new List<int> { 10000, 100000, 1000000, 10000000 }.ForEach(n =>
            {
                //CodeTimer.Time("Normal * " + n, n, () => Fib(12345, 29083));
                //CodeTimer.Time("Make * " + n, n, () => gcdMake(12345, 29083));
                //CodeTimer.Time("Fix * " + n, n, () => gcdFix(12345, 29083));
            });

            Console.WriteLine("press enter to exit...");
            Console.ReadLine();

        }
    }
}
